package com.jsecode.lib.util;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * TODO: 以后把队列处理部分提取出来
 * 
 * @author luodan
 *
 */
public class DataQueue<T> {
    private static final Logger logger = LoggerFactory.getLogger(DataQueue.class);
    
    private static final int DEFAULT_CAPACITY = 500 * 1000; // 
    protected BlockingQueue<T> dataQueue;
    // 队列的容量, 大于该大小, 将移除
    protected int capacity = DEFAULT_CAPACITY; //Integer.MAX_VALUE
    
    public DataQueue(){
        dataQueue = new LinkedBlockingQueue<T>(capacity);
    }
    
    public DataQueue(int capacity){
        this.capacity = capacity;
        dataQueue = new LinkedBlockingQueue<T>(capacity);
    }
    
    public BlockingQueue<T> getDataQueue(){
        return dataQueue;
    }
    
    // 数据队列的操作
    public void offerDataQueue(T data) {
        try{
            // 如果超过最大次数-1
            if (dataQueue.size() >= capacity) {
                logger.warn("removed the head of dataQueue for it's full. size = {} ", dataQueue.size());
                dataQueue.poll();
            }
            if(!dataQueue.offer(data, 10, TimeUnit.SECONDS)) {
                logger.warn("dataQueue is full. " + dataQueue.size());
            }
            if (logger.isDebugEnabled() && dataQueue.size() > (50 * 1000)) {
                logger.debug("Queue_default now size = {}" , dataQueue.size());
            }
        }catch(InterruptedException e){
            logger.error("Offer message error: " +  e.getMessage());
        }
    }
    
    public T takeDataQueue() {
        try{
            return dataQueue.take();
        }catch(InterruptedException e){
            logger.error("Take object from Queue error:" + e.getMessage());
        }
        return null;
    }
    
    public int drainTo(List<T> list, int maxElements) {
        return dataQueue.drainTo(list, maxElements);
    }
    
    /**
     * Returns the number of elements in this queue.
     *
     * @return the number of elements in this queue
     */
    public int size() {
        return dataQueue.size();
    }
    
    public int remainingCapacity() {
        return dataQueue.remainingCapacity();
    }
    
    /**
     * Atomically removes all of the elements from this queue.
     * The queue will be empty after this call returns.
     */
    public void clear() {
        dataQueue.clear();
    }
    
    public boolean isEmpty() {
        return dataQueue.isEmpty();
    }

}
